gl path "~/Dropbox/voter_id/Replication"

cap log close
log using "$path/table_a9.log", replace

use "$path/nc_dataset.dta" if new_reg == 0, clear

// drop 2018 
drop if inlist(election, 11, 12)

drop new_reg noid_p_2016 hispanic black white othernw

sort id election

replace voted = 0 if voted == .

// replace voted with NA if under 18 / ineligible in that election year 
drop if birth_year > 1998 & birth_year < 9999
replace voted = . if (birth_year > 1990 & birth_year < 9999) & (election == 1 | election == 2) // 2008
replace voted = . if (birth_year > 1992 & birth_year < 9999) & (election == 3 | election == 4) // 2010
replace voted = . if (birth_year > 1994 & birth_year < 9999) & (election == 5 | election == 6) // 2012
replace voted = . if (birth_year > 1996 & birth_year < 9999) & (election == 7 | election == 8) // 2014

** create string encoding of possible pre-treatment outcome paths
tostring voted, generate(outcome_path)

by id: gen outcome_path_pretreat = outcome_path[1] + outcome_path[2] + ///
								outcome_path[3] + outcome_path[4] + ///
								outcome_path[5] + outcome_path[6] + ///
								outcome_path[7] + outcome_path[8]

gen count = 1

// keep general only
keep if mod(election,2) == 0

// generate party interactions
gen una = dem == 0 & rep == 0
gen treat_dem = treat * dem
gen treat_una = treat * una
gen no_dmv_dem = no_dmv_match * dem
gen no_dmv_una = no_dmv_match * una

replace voted = 0 if voted == .

// construct age bins, give young voters who are ineligible for some election their own age bin
gen age_bin = 11 if (birth_year > 1990 & birth_year < 9999)
replace age_bin = 12 if (birth_year > 1992 & birth_year < 9999)
replace age_bin = 13 if (birth_year > 1994 & birth_year < 9999)
replace age_bin = 14 if (birth_year > 1996 & birth_year < 9999)
// give those who are eligible over the whole period their own age decile
xtile age_decile = birth_year if (birth_year <= 1990), nq(10)
replace age_bin = age_decile if (birth_year <= 1990)
drop age_decile

compress

sort id election

* vanilla diff in diff

reghdfe voted treat treat_dem treat_una, a(id election) cluster(id)
local b1 = _b[treat]
local se1 = _se[treat]
local b1_2 = _b[treat_dem]
local se1_2 = _se[treat_dem]
local b1_3 = _b[treat_una]
local se1_3 = _se[treat_una]
local n1 = e(N)
local nclust1 = e(N_clust)

* race by year
reghdfe voted treat treat_dem treat_una, a(id race_by_year) cluster(id)
local b2 = _b[treat]
local se2 = _se[treat]
local b2_2 = _b[treat_dem]
local se2_2 = _se[treat_dem]
local b2_3 = _b[treat_una]
local se2_3 = _se[treat_una]
local n2 = e(N)
local nclust2 = e(N_clust)

* age by year 
reghdfe voted treat treat_dem treat_una, a(id age_by_year) cluster(id)
local b3 = _b[treat]
local se3 = _se[treat]
local b3_2 = _b[treat_dem]
local se3_2 = _se[treat_dem]
local b3_3 = _b[treat_una]
local se3_3 = _se[treat_una]
local n3 = e(N)
local nclust3 = e(N_clust)

* age by race by year
reghdfe voted treat treat_dem treat_una, a(id race_by_age_by_year) cluster(id)
local b4 = _b[treat]
local se4 = _se[treat]
local b4_2 = _b[treat_dem]
local se4_2 = _se[treat_dem]
local b4_3 = _b[treat_una]
local se4_3 = _se[treat_una]
local n4 = e(N)
local nclust4 = e(N_clust)



preserve


collapse (sum) count (mean) voted, by(outcome_path_pretreat no_dmv_match no_dmv_dem no_dmv_una election)


*** get N by path by summing together n treated and n control
sort outcome_path no_dmv_match no_dmv_dem no_dmv_una election
// get treated units in each bin
gen tot_tmp = count if no_dmv_match & ///
	((no_dmv_match != no_dmv_match[_n-1]) | ///
	(no_dmv_dem != no_dmv_dem[_n-1]) | ///
	(no_dmv_una != no_dmv_una[_n-1])) 
// get treated units in outcome path
egen tot_treat = sum(tot_tmp), by(outcome_path)
// get control units in each outcome path
by outcome_path no_dmv_match no_dmv_dem no_dmv_una: replace tot_tmp = count[1] if _n == 1
// get total units in each outcome path
egen tot = sum(tot_tmp), by(outcome_path)
// N_voters is the number of voters who enter into the regression
egen N_voters = sum(tot_tmp)
// get number of elections
unique election
// N is number of voters * number of elections
gen long N = N_voters * r(unique)
drop tot_tmp
gen tot_control = tot - tot_treat

*** get weights for fw based on total n per stratum
*** each stratum has 10 obs
*** fw requires integers so need to round
gen tot2 = round(tot/10)
gen tot_treat2 = round(tot_treat/10)
egen op = group(outcome_path)


reghdfe voted no_dmv_match no_dmv_dem no_dmv_una [fw=tot_treat2], a(op election)
local b5 = _b[no_dmv_match]
local se5 = _se[no_dmv_match]
local b5_2 = _b[no_dmv_dem]
local se5_2 = _se[no_dmv_dem]
local b5_3 = _b[no_dmv_una]
local se5_3 = _se[no_dmv_una]
local n5 = N 
local nclust5 = N_voters


* match on pre-treatment turnout path and race

restore
preserve

collapse (sum) count (mean) voted, by(outcome_path_pretreat no_dmv_match no_dmv_dem no_dmv_una race_string election)

*** get N by path by summing together n treated and n control
sort outcome_path no_dmv_match race_string no_dmv_dem no_dmv_una election
// get treated units in each bin
gen tot_tmp = count if no_dmv_match & ///
	((no_dmv_match != no_dmv_match[_n-1]) | ///
	(no_dmv_dem != no_dmv_dem[_n-1]) | ///
	(no_dmv_una != no_dmv_una[_n-1])) 
// get treated units in outcome path and race
egen tot_treat = sum(tot_tmp), by(outcome_path race_string)
// get control units in each outcome path by race
by outcome_path no_dmv_match race_string no_dmv_dem no_dmv_una: replace tot_tmp = count[1] if _n == 1
// get total units in each outcome path
egen tot = sum(tot_tmp), by(outcome_path race_string)
// N_voters is the number of voters who enter into the regression
egen N_voters = sum(tot_tmp)
// get number of elections
unique election
// N is number of voters * number of elections
gen long N = N_voters * r(unique)
drop tot_tmp
gen tot_control = tot - tot_treat

*** get weights for fw based on total n per stratum
*** each stratum has 10 obs
*** fw requires integers so need to round
gen tot2 = round(tot/10)
gen tot_treat2 = round(tot_treat/10)
egen op = group(outcome_path race_string)

reghdfe voted no_dmv_match no_dmv_dem no_dmv_una [fw=tot_treat2], a(op election)
local b6 = _b[no_dmv_match]
local se6 = _se[no_dmv_match]
local b6_2 = _b[no_dmv_dem]
local se6_2 = _se[no_dmv_dem]
local b6_3 = _b[no_dmv_una]
local se6_3 = _se[no_dmv_una]
local n6 = N
local nclust6 = N_voters


restore

collapse (sum) count (mean) voted, by(outcome_path_pretreat no_dmv_match no_dmv_dem no_dmv_una race_string age_bin election)

drop if age_bin == . 

*** get N by path by summing together n treated and n control
sort outcome_path no_dmv_match race_string age_bin no_dmv_dem no_dmv_una election
// get treated units in each bin
gen tot_tmp = count if no_dmv_match & ///
	((no_dmv_match != no_dmv_match[_n-1]) | ///
	(no_dmv_dem != no_dmv_dem[_n-1]) | ///
	(no_dmv_una != no_dmv_una[_n-1]) | ///
	(age_bin != age_bin[_n-1]))
// get treated units in outcome path and race and age bin
egen tot_treat = sum(tot_tmp), by(outcome_path race_string age_bin)
// get control units in each outcome path by race and age_bin
by outcome_path no_dmv_match race_string age_bin no_dmv_dem no_dmv_una: replace tot_tmp = count[1] if _n == 1
// get total units in each outcome path race and age bin
egen tot = sum(tot_tmp), by(outcome_path race_string age_bin)
// N_voters is the number of voters who enter into the regression
egen N_voters = sum(tot_tmp)
// get number of elections
unique election
// N is number of voters * number of elections
gen long N = N_voters * r(unique)
drop tot_tmp
gen tot_control = tot - tot_treat

*** get weights for fw based on total n per stratum
*** each stratum has 10 obs
*** fw requires integers so need to round
gen tot2 = round(tot/10)
gen tot_treat2 = round(tot_treat/10)
egen op = group(outcome_path race_string age_bin)

reghdfe voted no_dmv_match no_dmv_dem no_dmv_una [fw=tot_treat2], a(op election)
local b7 = _b[no_dmv_match]
local se7 = _se[no_dmv_match]
local b7_2 = _b[no_dmv_dem]
local se7_2 = _se[no_dmv_dem]
local b7_3 = _b[no_dmv_una]
local se7_3 = _se[no_dmv_una]
local n7 = N
local nclust7 = N_voters

log close

quietly {
	cap log close
	set linesize 255
	log using "$path/table_a9.tex", text replace
	
	noisily dis "\begin{table}[t]"
	noisily dis "\centering"
	noisily dis "\caption{\textbf{Effect of Voter ID Law on General Election Turnout Among Those Without ID, Individual Level, 2008--2016.}"
	noisily dis "\label{tab:diff_in_diff_g_party}}"
	noisily dis "\resizebox{\textwidth}{!} {"
	noisily dis "\begin{tabular}{lccccccc}"
	noisily dis "\toprule \toprule"
	noisily dis " & \multicolumn{7}{c}{Voted in General (0-1)}\\"
	noisily dis " & (1) & (2) & (3) & (4) & (5) & (6) & (7)  \\"
	noisily dis "\midrule"
	noisily dis "No DMV * 2016 & " %4.3f `b1' " & " %4.3f `b2' " & " %4.3f `b3' " & " %4.3f `b4' " & " %4.3f `b5' " & " %4.3f `b6' " & " %4.3f `b7'  "\\"
	noisily dis " & (" %4.3f `se1' ") & (" %4.3f `se2' ") & (" %4.3f `se3' ") & (" %4.3f `se4' ") & (" %4.3f `se5' ") & (" %4.3f `se6' ") & (" %4.3f `se7' ") \smallskip\\"
	noisily dis "No DMV * 2016 * Dem & " %4.3f `b1_2' " & " %4.3f `b2_2' " & " %4.3f `b3_2' " & " %4.3f `b4_2' " & " %4.3f `b5_2' " & " %4.3f `b6_2' " & " %4.3f `b7_2' "\\"
	noisily dis " & (" %4.3f `se1_2' ") & (" %4.3f `se2_2' ") & (" %4.3f `se3_2' ") & (" %4.3f `se4_2' ") & (" %4.3f `se5_2' ") & (" %4.3f `se6_2' ") & (" %4.3f `se7_2' ") \smallskip\\"
	noisily dis "No DMV * 2016 * Unaffil & " %4.3f `b1_3' " & " %4.3f `b2_3' " & " %4.3f `b3_3' " & " %4.3f `b4_3' " & " %4.3f `b5_3' " & " %4.3f `b6_3' " & " %4.3f `b7_3'  "\\"
	noisily dis " & (" %4.3f `se1_3' ") & (" %4.3f `se2_3' ") & (" %4.3f `se3_3' ") & (" %4.3f `se4_3' ") & (" %4.3f `se5_3' ") & (" %4.3f `se6_3' ") & (" %4.3f `se7_3' ") \smallskip\\"

	noisily dis " N & " %12.0fc `n1' " & " %12.0fc `n2' " & " %12.0fc `n3' " & " %12.0fc `n4' " & " %12.0fc `n5' " & " %12.0fc `n6' " & " %12.0fc `n7' " \\ "
	noisily dis " \# Voters & "  %12.0fc `nclust1' " & " %12.0fc `nclust2' " & " %12.0fc `nclust3' " & " %12.0fc `nclust4' " & " %12.0fc `nclust5' " & " %12.0fc `nclust6' " & " %12.0fc `nclust7' " \\ "
	
	noisily dis "Individual FEs & Y & Y & Y & Y & N & N & N \\"
	noisily dis "Year FEs & Y & N & N & N & Y & Y & Y  \\"
	noisily dis "Race by Year FEs & N & Y & N & N & N & N & N  \\"
	noisily dis "Age by Year FEs & N & N & Y & N & N & N & N \\"
	noisily dis "Race by Age by Year FEs & N & N & N & Y & N & N & N \\"
	noisily dis "Exact Match on Turnout & N & N & N & N & Y & Y & Y \\"
	noisily dis "Exact Match on Race & N & N & N & N & N & Y & Y \\"
	noisily dis "Exact Match on Age Bin & N & N & N & N & N & N & Y \\"

	noisily dis "\bottomrule \bottomrule"
	noisily dis "\multicolumn{8}{p{1.15\textwidth}}{\footnotesize Robust standard errors clustered by individual in parentheses.  Main effects for No DMV Match and 2016 are absorbed by fixed effects.  "
	noisily dis "Exact matching on turnout matches units based on all primary and general elections from the 2008 primary through the 2014 general.  For exact matching on age, we construct a separate age bin for "
	noisily dis "each group of voters who were under 18 for a given set of elections, so the cohort of voters who became newly eligible to participate in 2010, 2012, 2014, and 2016 each have their own age bin.  "
	noisily dis "For voters who were eligible for all elections since 2008, we construct age deciles.}"
	noisily dis "\end{tabular}}"
	noisily dis "\end{table}"
	
	log off
	
}




